package com.gcl.system;

import javax.xml.crypto.Data;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class FinanceManager {
    private ArrayList<Record> incomes=new ArrayList<>();
    private ArrayList<Record> expenses=new ArrayList<>();
    private Map<Integer, Integer> monthlyIncomes = new HashMap<>(); // 存储每月收入，键为年月（如202401），值为预算金额
    private Map<Integer, Integer> monthlyExpenses = new HashMap<>(); // 存储每月实际支出，键为年月
    private Map<Integer, Integer> monthlyBudgets = new HashMap<>(); // 存储每月预算，键为年月（如202401），值为预算金额

    public FinanceManager(){}

    public FinanceManager(ArrayList<Record> incomes, ArrayList<Record> expenses) {
        this.incomes = incomes;
        this.expenses = expenses;
    }

    //方法:记录收入
    public void addIncome(Date date, int money, String notes, String category){
        if(money<=0){
            System.out.println("收入金额必须为正数");
            return;
        }else{
            incomes.add(new Record(date,money,notes,category));
            // 使用Calendar获取年份和月份
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH) + 1; // 月份从0开始
            // 更新每月收入
            int incomeForMonth = monthlyIncomes.getOrDefault(year * 100 + month, 0);
            monthlyIncomes.put(year * 100 + month, incomeForMonth + money);
        }
    }

    //方法:记录支出
    public void addExpenses(Date date,int money,String notes,String category){
        if(money<=0){
            System.out.println("支出金额必须为正数");
            return;
        }else{
            expenses.add(new Record(date,money,notes,category));
            // 使用Calendar获取年份和月份
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH) + 1; // 月份从0开始

            // 更新每月支出
            int expensesForMonth = monthlyExpenses.getOrDefault(year * 100 + month, 0);
            monthlyExpenses.put(year * 100 + month, expensesForMonth + money);
        }
    }
    // 展示所有账单记录
    public void displayAllRecords() {
        System.out.println("所有收入记录：");
        for (Record income : incomes) {
            System.out.println(income);
        }
        System.out.println("所有支出记录：");
        for (Record expense : expenses) {
            System.out.println(expense);
        }
    }
    // 按日期查询账单
    public void queryByDate(Date date) {
        System.out.println("指定日期的收入记录：");
        for (Record income : incomes) {
            if (income.getDate().equals(date)) {
                System.out.println(income);
            }
        }
        System.out.println("指定日期的支出记录：");
        for (Record expense : expenses) {
            if (expense.getDate().equals(date)) {
                System.out.println(expense);
            }
        }
    }

    // 按日期范围(不包括起始和结束当天)查询账单
    public void queryByDateRange1(Date startDate, Date endDate) {
        System.out.println("指定日期范围内的收入记录：");
        for (Record income : incomes) {
            if (income.getDate().after(startDate) && income.getDate().before(endDate)) {
                System.out.println(income);
            }
        }
        System.out.println("指定日期范围内的支出记录：");
        for (Record expense : expenses) {
            if (expense.getDate().after(startDate) && expense.getDate().before(endDate)) {
                System.out.println(expense);
            }
        }
    }
    // 按日期范围查询账单
    public void queryByDateRange2(Date startDate, Date endDate) {
        System.out.println("指定日期范围内的收入记录：");
        for (Record income : incomes) {
            if (income.getDate().compareTo(startDate) >= 0 && income.getDate().compareTo(endDate) <= 0) {
                System.out.println(income);
            }
        }
        System.out.println("指定日期范围内的支出记录：");
        for (Record expense : expenses) {
            if (expense.getDate().compareTo(startDate) >= 0 && expense.getDate().compareTo(endDate) <= 0) {
                System.out.println(expense);
            }
        }
    }

    // 按类别查询账单
    public void queryByCategory(String category) {
        System.out.println("指定类别的收入记录：");
        for (Record income : incomes) {
            if (income.getCategory().equals(category)) {
                System.out.println(income);
            }
        }
        System.out.println("指定类别的支出记录：");
        for (Record expense : expenses) {
            if (expense.getCategory().equals(category)) {
                System.out.println(expense);
            }
        }
    }
    // 设置月度预算
    public void setMonthlyBudget(int year, int month, int budget) {
        int key=year * 100 + month;
        monthlyBudgets.put(key, budget);
        //System.out.println("设置预算: 年月=" + key + ", 预算=" + budget);

    }

    // 获取某月的总支出
    private int getMonthlyExpenses(int year, int month) {
        return monthlyExpenses.getOrDefault(year * 100 + month, 0);
    }
    // 获取当前剩余可用预算
    public int getRemainingBudgetForCurrentMonth() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1; // 月份从0开始，所以加1

        return getRemainingBudget(year, month);
    }

    // 根据年和月获取剩余预算
    private int getRemainingBudget(int year, int month) {
        int key = year * 100 + month;
        int totalExpenses = getMonthlyExpenses(year, month);
        int budget = monthlyBudgets.getOrDefault(year * 100 + month, 0);
        int remaining = budget - totalExpenses;
        //System.out.println("预算: 年月=" + key + ", 预算=" + budget + ", 支出=" + totalExpenses + ", 剩余=" + remaining);
        return remaining;
    }

    // 月度统计
    public void monthlyStatistics(int year, int month) {
        System.out.println("年份：" + year + "，月份：" + month);
        int totalIncome = 0;
        int totalExpense = 0;
        Map<String, Integer> categoryExpenses = new HashMap<>();

        for (Record income : incomes) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(income.getDate());
            int incomeYear = calendar.get(Calendar.YEAR);
            int incomeMonth = calendar.get(Calendar.MONTH) + 1;

            if (incomeYear == year && incomeMonth == month) {
                totalIncome += income.getMoney();
            }
        }

        for (Record expense : expenses) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(expense.getDate());
            int expenseYear = calendar.get(Calendar.YEAR);
            int expenseMonth = calendar.get(Calendar.MONTH) + 1;

            if (expenseYear == year && expenseMonth == month) {
                totalExpense += expense.getMoney();
                categoryExpenses.put(expense.getCategory(), categoryExpenses.getOrDefault(expense.getCategory(), 0) + expense.getMoney());
            }
        }

        System.out.println("总收入：" + totalIncome);
        System.out.println("总支出：" + totalExpense);
        System.out.println("各类别支出：");
        categoryExpenses.forEach((category, amount) -> System.out.println(category + "：" + amount));

    }

    public static void main(String[] args) {
        //创建类的实例
        FinanceManager manager=new FinanceManager();
        Scanner sc=new Scanner(System.in);
        while(true){
            System.out.println("======== 财务管理系统 ========");
            System.out.println("1. 记录收入");
            System.out.println("2. 记录支出");
            System.out.println("3. 展示所有账单");
            System.out.println("4. 按日期查询账单");
            System.out.println("5. 按日期范围(不含起始和结束)查询账单");
            System.out.println("6. 按日期范围(含起始和结束)查询账单");
            System.out.println("7. 按类别查询账单");
            System.out.println("8. 设置预算限额");
            System.out.println("9. 查看月度统计报告");
            System.out.println("10. 退出程序");
            System.out.println("请输入操作选项（1-10）：");

            int choice=sc.nextInt();
            sc.nextLine(); // 添加这行代码来消耗掉行尾的换行符
            if(choice==1){
                System.out.println("请输入日期(格式:yyyy--MM--dd)");
                SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy--MM--dd");
                Date date=null;
                try {
                    String datestr=sc.nextLine();
                    date=dateFormat.parse(datestr);//将用户输入的日期字符串转化为Date对象
                }catch(ParseException e){
                    System.out.println("日期格式错误,请重新输入");
                }

                System.out.println("请输入收入金额");
                int money=sc.nextInt();
                sc.nextLine(); // 添加这行代码来消耗掉行尾的换行符
                System.out.println("请输入收入类别");
                String category=sc.nextLine();
                System.out.println("请输入备注");
                String notes=sc.nextLine();
                manager.addIncome(date,money,notes,category);
            }else if(choice==2){
                System.out.println("请输入日期(格式:yyyy--MM--dd)");
                SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy--MM--dd");
                Date date=null;
                try{
                    String datestr=sc.nextLine();
                    date= dateFormat.parse(datestr);
                }catch(ParseException e){
                    System.out.println("日期格式错误,请重新输入");
                }
                System.out.println("请输入支出金额");
                int money=sc.nextInt();
                sc.nextLine(); // 添加这行代码来消耗掉行尾的换行符
                System.out.println("请输入支出类别");
                String category=sc.nextLine();
                System.out.println("请输入备注");
                String notes=sc.nextLine();
                manager.addExpenses(date,money,notes,category);
                System.out.println("当前月份的剩余可用预算：" + manager.getRemainingBudgetForCurrentMonth());
            }else if(choice==3){
                manager.displayAllRecords();
                System.out.println("当前月份的剩余可用预算：" + manager.getRemainingBudgetForCurrentMonth());
            }else if(choice==4){
                System.out.println("请输入查询账单的日期 (格式: yyyy--MM--dd)");
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy--MM--dd");
                Date queryDate = null;
                try {
                    String dateStr = sc.nextLine();
                    queryDate = dateFormat.parse(dateStr);
                } catch (ParseException e) {
                    System.out.println("日期格式错误，请重新输入");
                    break;
                }
                manager.queryByDate(queryDate);
            }else if(choice==5){
                System.out.println("请输入查询账单的开始日期 (格式: yyyy--MM--dd)");
                SimpleDateFormat dateFormatRange = new SimpleDateFormat("yyyy--MM--dd");
                Date startDate = null, endDate = null;
                try {
                    String startDateStr = sc.nextLine();
                    startDate = dateFormatRange.parse(startDateStr);
                } catch (ParseException e) {
                    System.out.println("开始日期格式错误，请重新输入");
                }
                try {
                    System.out.println("请输入查询账单的结束日期 (格式: yyyy--MM--dd)");
                    String endDateStr = sc.nextLine();
                    endDate = dateFormatRange.parse(endDateStr);
                } catch (ParseException e) {
                    System.out.println("结束日期格式错误，请重新输入");
                }
                manager.queryByDateRange1(startDate, endDate);
            }else if(choice==6){
                System.out.println("请输入查询账单的开始日期 (格式: yyyy--MM--dd)");
                SimpleDateFormat dateFormatRange = new SimpleDateFormat("yyyy--MM--dd");
                Date startDate = null, endDate = null;
                try {
                    String startDateStr = sc.nextLine();
                    startDate = dateFormatRange.parse(startDateStr);
                } catch (ParseException e) {
                    System.out.println("开始日期格式错误，请重新输入");
                }
                try {
                    System.out.println("请输入查询账单的结束日期 (格式: yyyy--MM--dd)");
                    String endDateStr = sc.nextLine();
                    endDate = dateFormatRange.parse(endDateStr);
                } catch (ParseException e) {
                    System.out.println("结束日期格式错误，请重新输入");
                }
                manager.queryByDateRange2(startDate, endDate);
            }
            else if(choice==7){
                System.out.println("请输入查询账单的类别");
                String category = sc.nextLine();
                manager.queryByCategory(category);
            }else if(choice==8){
                System.out.println("请输入年份和月份设置预算（格式：yyyyMM）");
                int yearMonth = sc.nextInt();
                sc.nextLine();
                System.out.println("请输入预算金额");
                int budget = sc.nextInt();
                manager.setMonthlyBudget(yearMonth / 100, yearMonth % 100, budget);
                System.out.println("当前月份的剩余可用预算：" + manager.getRemainingBudgetForCurrentMonth());
            }else if(choice==9){
                System.out.println("请输入年份和月份查看统计（格式：yyyyMM）");
                int yearMonth = sc.nextInt();
                sc.nextLine();
                manager.monthlyStatistics(yearMonth / 100, yearMonth % 100);
                System.out.println("当前月份的剩余可用预算：" + manager.getRemainingBudgetForCurrentMonth());
            }
            else if (choice == 10) {
                System.out.println("退出程序。");
                sc.close();
                System.exit(0);
            }
            else{
                System.out.println("无效选择,请重新输入");
                continue;
            }
        }
    }
}
